#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <semaphore.h>

#ifndef LIBRAID1_H_
#define LIBRAID1_H_

#define MAX_BUFFER 4163
#define MAX_THREADS 4163
#define MAX_CONNECTIONS 65535
#define BUFFER_TIEMPO 11

struct {
	unsigned char type;
	uint32_t pLength;
	char *payLoad;
}typedef t_paquete;

typedef struct t_paquete_lectura {
	char type;
	int16_t pLength;
	uint64_t* payLoad;
}__attribute__((packed)) t_paquete_lectura;

struct nodoCola {
	t_paquete infoCola;
	struct nodoCola *sig;
}typedef nodoCola;

struct {
	char *id;
	char *ip;
	uint64_t tiempoDeEspera;
	uint32_t puerto;
	uint32_t fileDescriptor;
}typedef tInfoLista;

struct nodoLista {
	tInfoLista infoLista;
	struct nodoLista *sig;
}typedef nodoLista;

struct {
	uint8_t booleanLectura;
	uint8_t flagConsola;
	uint32_t PPDpuerto;
	uint32_t PPDidSize;
	uint32_t PPDipSize;
	uint32_t numeroCliente;
	uint64_t PPDsectores;
	int64_t fileDescriptor;
	int64_t bytesRecibidos;
	tInfoLista registroNuevo;
	t_paquete nuevoPaquete;
	t_paquete paqueteSincro;
	t_paquete_lectura paqueteLectura;
	nodoLista *nodoSincronizacion;
	nodoLista *nodoLectura;
	char *PPDidentificador;
	char *PPDip;
	char *buferLectura;
	char *bufCrudo;
	char *bufTiempo;
	char *respuestaProcesamiento;
	char *errorCeroPlanificadores;
	char *errorYaExiste;
	char *errorSectoresInsuficientes;
	char *paqueteSincroDescerealizado;
}typedef variablesCliente;

void atenderCliente(variablesCliente*);
void imprimirLista(void);
void parsearConfiguracion(char*, char**, uint8_t*);
void buscarQuitar(char*);
void insertarFIFO(tInfoLista);
void procesarPaquete(t_paquete, char**, char**, uint64_t*, char**, uint32_t*, uint32_t*, uint32_t*);
t_paquete empaquetar(char*);
int8_t paqueteLecturaAPaquete(t_paquete_lectura, t_paquete*);
int8_t desempaquetar(t_paquete, char**);
uint16_t confirmacion(uint32_t);
uint64_t potencia(uint16_t, uint16_t);
uint32_t matar(char*, uint16_t);
uint32_t existePPD(char*);
uint32_t contarNodos(void);
nodoLista *buscarNodo(char*);
nodoLista *nodoConMenosTiempo(void);
int8_t esPaqueteLectura(char);
uint32_t conectar(char*, uint32_t);

#endif /* LIBRAID1_H_ */
